package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dao.DishDao;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.entity.dto.dish.DishAddDTO;
import com.itheima.reggie.entity.dto.dish.DishFlavorDTO;
import com.itheima.reggie.entity.dto.dish.DishUpdateDTO;
import com.itheima.reggie.entity.vo.DishVo;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.web.R;
import com.itheima.reggie.web.exception.BusinessException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜品业务层实现类
 *
 * @Name : DishServiceImpl
 * @Author : WuQiang
 * @Date : 2022-08-014 16:18
 * @Description : 菜品业务层实现类
 */
@Service
@Transactional
public class DishSexrviceImpl extends ServiceImpl<DishDao, Dish>
        implements DishService {

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private DishFlavorService dishFlavorService;


    @Override
    public R getPage(Long page, Long pageSize, String name) {
        Page<Dish> pageCondition = new Page<>(page, pageSize);
        LambdaQueryWrapper<Dish> lqw = Wrappers.lambdaQuery(Dish.class);
        //根据菜品名称模糊查询
        lqw.like(StringUtils.isNotBlank(name), Dish::getName, name)
                .orderByAsc(Dish::getSort)
                .orderByDesc(Dish::getUpdateTime);
        this.page(pageCondition, lqw);
        List<Dish> dishes = pageCondition.getRecords();

        //查询菜品分类集合
        List<Category> categoryList = categoryService.getList(1);

        List<DishVo> dishVos = dishes.stream().map(dish -> {
            //创建返回值对象
            DishVo dishVo = new DishVo();
            BeanUtils.copyProperties(dish, dishVo);

            //设置菜品套餐名
            Category cate = categoryList.stream()
                    .filter(category -> category.getId().equals(dishVo.getCategoryId()))
                    .findFirst()
                    .get();
            dishVo.setCategoryName(cate.getName());
            return dishVo;
        }).collect(Collectors.toList());
     /*   //创建前端需要的返回结果集合
        ArrayList<DishVo> dishVos = new ArrayList<>();
        for (Dish dish : dishes) {
            //创建返回值对象
            DishVo dishVo = new DishVo();
            BeanUtils.copyProperties(dish, dishVo);
//            //查询菜品分类名称
//            Category category = categoryService.getOne(Wrappers.lambdaQuery(Category.class)
//                    .eq(Category::getId, dish.getCategoryId()));
            //优化频繁查询数据库的问题
            for (Category category : categoryList) {
                if (category.getId().equals(dish.getCategoryId())) {
                    dishVo.setCategoryName(category.getName());
                    break;
                }
            }
            //查询菜品口味
//            List<DishFlavor> dishFlavors = dishFlavorService.list(Wrappers.lambdaQuery(DishFlavor.class)
//                    .eq(DishFlavor::getDishId, dish.getId()));
//            dishVo.setFlavors(dishFlavors);
            //添加进返回值集合
            dishVos.add(dishVo);
        }*/
        Page<DishVo> dishVoPage = new Page<>();
        BeanUtils.copyProperties(pageCondition, dishVoPage);
        dishVoPage.setRecords(dishVos);
        return R.success("分页查询成功", dishVoPage);
    }

    @Override
    public Boolean bulkOperations(Integer status, Long[] ids) {
        List<Long> dishIds = Arrays.asList(ids);
        List<Dish> dishArrayList = new ArrayList<>();
        for (Long id : dishIds) {
            Dish dish = new Dish();
            dish.setId(id);
            dish.setStatus(status);
            dishArrayList.add(dish);
        }
        return this.updateBatchById(dishArrayList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveWithName(DishAddDTO dto) {
        //核心业务
        //菜品名唯一性校验
        int count = this.count(Wrappers.lambdaQuery(Dish.class)
                .eq(Dish::getName, dto.getName()));
        if (count > 0) {
            throw new BusinessException("菜品名称：" + dto.getName() + "已经存在");
        }

        //增加菜品业务
        Dish dish = new Dish();
        BeanUtils.copyProperties(dto, dish);
        boolean result = this.save(dish);
        if (result) {
            //新增菜品成功
            List<DishFlavorDTO> flavors = dto.getFlavors();
            if (flavors == null || flavors.size() <= 0) {
                //用户未选择口味信息
                return true;
            }
            //创建批量添加口味的集合
            List<DishFlavor> dishFlavors = new ArrayList<>();
            for (DishFlavorDTO flavor : flavors) {
                //创建菜品口味对象
                DishFlavor dishFlavor = new DishFlavor();
                BeanUtils.copyProperties(flavor, dishFlavor);
                dishFlavor.setDishId(dish.getId());
                dishFlavors.add(dishFlavor);
            }
            dishFlavorService.saveBatch(dishFlavors);
            return true;
        }
        return false;
    }

    @Override
    public DishVo getDishAndDishFlaverById(Long id) {
        //菜品名称唯一性校验
        Dish dish = this.getById(id);
        //通过菜品id查询口味表中的数据
        List<DishFlavor> dishFlavors = dishFlavorService.list(Wrappers.lambdaQuery(DishFlavor.class)
                .eq(DishFlavor::getDishId, dish.getId()));
        //创建返回值对象
        DishVo dishVo = new DishVo();
        BeanUtils.copyProperties(dish, dishVo);
        dishVo.setFlavors(dishFlavors);
        return dishVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDishAndDishFlavor(DishUpdateDTO dto) {
        //核心业务
        //菜品名称唯一性校验
        List<Dish> dishes = this.list(Wrappers.lambdaQuery(Dish.class)
                .eq(Dish::getName, dto.getName()));
        if (dishes != null || dishes.size() > 0) {
            for (Dish dish : dishes) {
                //排除点是自己修改的情况
                if (!dish.getId().equals(dto.getId())) {
                    throw new BusinessException("菜品名称" + dto.getName() + "已经存在");
                }
            }
        }

        //修改逻辑
        Dish dish = new Dish();
        BeanUtils.copyProperties(dto, dish);
        //修改菜品
        boolean result = this.updateById(dish);
        if (result) {
            //先删除对应口味表中的口味信息
            dishFlavorService.remove(Wrappers.lambdaQuery(DishFlavor.class)
                    .eq(DishFlavor::getDishId, dish.getId()));
            //在插入新的口味信息
            List<DishFlavor> flavors = dto.getFlavors();
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dish.getId());
            }
            dishFlavorService.saveBatch(flavors);
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(List<Long> idList) {
        //核心业务
        for (Long dishId : idList) {
            //删除菜品之前先查询套餐表是否有套餐包含该菜品
            int count = setmealDishService.count(Wrappers.lambdaQuery(SetmealDish.class)
                    .eq(SetmealDish::getDishId, dishId));
            if (count > 0) {
                throw new BusinessException("当前菜品在套餐类包含，不能删除");
            }
            //删除菜品业务
            this.removeById(dishId);
            //删除对应口味表中的数据
            dishFlavorService.remove(Wrappers.lambdaQuery(DishFlavor.class)
                    .eq(DishFlavor::getDishId, dishId));
        }

        return true;
    }
}




